//
//  DeviceManager.swift
//  SwiftProject
//
//  Created by qindong on 2021/3/4.
//

import UIKit

//MARK:- 变量-编译相关
/// 判断当前是否是debug编译模式
var DEBUG : Bool {
    #if DEBUG
        return true
    #else
        return false
    #endif
}

//MARK:- 变量-设备相关
///设备类型
let IS_IPAD : Bool = QMUIHelper.isIPad
let IS_IPOD : Bool = QMUIHelper.isIPod
let IS_IPHONE : Bool = QMUIHelper.isIPhone
let IS_SIMULATOR : Bool = QMUIHelper.isSimulator
let IS_MAC : Bool = QMUIHelper.isMac

let IOS_VERSION_STRING : String = UIDevice.current.systemVersion
/// 操作系统版本号，只获取第二级的版本号，例如 10.3.1 只会得到 10.3
let IOS_VERSION : Double = Double(UIDevice.current.systemVersion)!

/// 数字形式的操作系统版本号，可直接用于大小比较；如 110205 代表 11.2.5 版本；根据 iOS 规范，版本号最多可能有3位
let IOS_VERSION_NUMBER : Int = QMUIHelper.numbericOSVersion()

/// 是否横竖屏
/// 用户界面横屏了才会返回YES
let IS_LANDSCAPE : Bool = UIApplication.shared.statusBarOrientation.isLandscape

/// 无论支不支持横屏，只要设备横屏了，就会返回YES
let IS_DEVICE_LANDSCAPE : Bool = UIDevice.current.orientation.isLandscape

/// 屏幕宽度，会根据横竖屏的变化而变化
let SCREEN_WIDTH : CGFloat = UIScreen.main.bounds.size.width

/// 屏幕高度，会根据横竖屏的变化而变化
let SCREEN_HEIGHT : CGFloat = UIScreen.main.bounds.size.height

/// 是否全面屏设备
let IS_NOTCHED_SCREEN : Bool = QMUIHelper.isNotchedScreen

//MARK:- 变量-布局相关
/// toolBar相关frame
let ToolBarHeight : CGFloat = IS_IPAD ? (IS_NOTCHED_SCREEN ? 70 : (IOS_VERSION >= 12.0 ? 50 : 44)) : (IS_LANDSCAPE ? PreferredValueForVisualDevice(regular: 44, compace: 32) : 44) + SafeAreaInsetsConstantForDeviceWithNotch.bottom

/// tabBar相关frame
let TabBarHeight : CGFloat = IS_IPAD ? (IS_NOTCHED_SCREEN ? 65 : (IOS_VERSION >= 12.0 ? 50 : 49)) : (IS_LANDSCAPE ? PreferredValueForVisualDevice(regular: 49, compace: 32) : 49) + SafeAreaInsetsConstantForDeviceWithNotch.bottom

/// 状态栏高度(来电等情况下，状态栏高度会发生变化，所以应该实时计算，iOS 13 起，来电等情况下状态栏高度不会改变)
let StatusBarHeight : CGFloat = UIApplication.shared.isStatusBarHidden ? 0 : UIApplication.shared.statusBarFrame.size.height

/// navigationBar 的静态高度
let NavigationBarHeight : CGFloat = IS_IPAD ? (IOS_VERSION >= 12.0 ? 50 : 44) : (IS_LANDSCAPE ? PreferredValueForVisualDevice(regular: 44, compace: 32) : 44)

/// 代表(导航栏+状态栏)，这里用于获取其高度
/// @warn 如果是用于 viewController，请使用 UIViewController(QMUI) qmui_navigationBarMaxYInViewCoordinator 代替
let NavigationContentTop : CGFloat = StatusBarHeight + NavigationBarHeight

/// iPhoneX 系列全面屏手机的安全区域的静态值
let SafeAreaInsetsConstantForDeviceWithNotch : UIEdgeInsets = QMUIHelper.safeAreaInsetsForDeviceWithNotch

/// 获取一个像素
let PixelOne : CGFloat = QMUIHelper.pixelOne

/// 将所有屏幕按照宽松/紧凑分类，其中 iPad、iPhone XS Max/XR/Plus 均为宽松屏幕，但开启了放大模式的设备均会视为紧凑屏幕
func PreferredValueForVisualDevice(regular : CGFloat, compace : CGFloat) -> CGFloat {
    QMUIHelper.isRegularScreen ? regular : compace
}

/// 区分全面屏和非全面屏
func PreferredValueForNotchedDevice(notchedDevice : CGFloat, otherDevice : CGFloat) -> CGFloat {
    QMUIHelper.isNotchedScreen ? notchedDevice : otherDevice
}

//MARK:- app信息相关
/// app版本
let AppVersion : String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
/// app Build版本
let AppBuildVersion : String = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String
/// app名称
let AppName : String = Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
/// project名称
let ProjectName : String = Bundle.main.object(forInfoDictionaryKey: kCFBundleExecutableKey as String) as! String
/// bundleId
let BundleId : String = Bundle.main.object(forInfoDictionaryKey: kCFBundleIdentifierKey as String) as! String

class DeviceManager: NSObject {
    //MARK:- 获取设备类型
    static var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }

        switch identifier {
        case "iPod1,1" : return "iPod Touch 1"
        case "iPod2,1" : return "iPod Touch 2"
        case "iPod3,1" : return "iPod Touch 3"
        case "iPod4,1" : return "iPod Touch 4"
        case "iPod5,1" : return "iPod Touch 5"
        case "iPod7,1" : return "iPod Touch 6"
        case "iPod9,1" : return "iPod touch 7"

        case "iPhone3,1", "iPhone3,2", "iPhone3,3" : return "iPhone 4"
        case "iPhone4,1" : return "iPhone 4s"
        case "iPhone5,1" : return "iPhone 5"
        case "iPhone5,2" : return "iPhone 5 (GSM+CDMA)"
        case "iPhone5,3" : return "iPhone 5c (GSM)"
        case "iPhone5,4" : return "iPhone 5c (GSM+CDMA)"
        case "iPhone6,1" : return "iPhone 5s (GSM)"
        case "iPhone6,2" : return "iPhone 5s (GSM+CDMA)"
        case "iPhone7,2" : return "iPhone 6"
        case "iPhone7,1" : return "iPhone 6 Plus"
        case "iPhone8,1" : return "iPhone 6s"
        case "iPhone8,2" : return "iPhone 6s Plus"
        case "iPhone8,4" : return "iPhone SE"

        case "iPhone9,1" : return "国行、日版、港行iPhone 7"
        case "iPhone9,2" : return "港行、国行iPhone 7 Plus"
        case "iPhone9,3" : return "美版、台版iPhone 7"
        case "iPhone9,4" : return "美版、台版iPhone 7 Plus"
        case "iPhone10,1", "iPhone10,4" : return "iPhone 8"
        case "iPhone10,2", "iPhone10,5" : return "iPhone 8 Plus"
        case "iPhone10,3", "iPhone10,6" : return "iPhone X"
        case "iPhone11,2" : return "iPhone XS"
        case "iPhone11,4", "iPhone11,6" : return "iPhone XS Max"
        case "iPhone11,8" : return "iPhone XR"
        case "iPhone12,1" : return "iPhone 11"
        case "iPhone12,3" : return "iPhone 11 Pro"
        case "iPhone12,5" : return "iPhone 11 Pro Max"
        case "iPhone12,8" : return "iPhone SE (2nd generation)"
        case "iPhone13,1" : return "iPhone 12 mini"
        case "iPhone13,2" : return "iPhone 12"
        case "iPhone13,3" : return "iPhone 12 Pro"
        case "iPhone13,4" : return "iPhone 12 Pro Max"
        case "iPhone14,4" : return "iPhone 13 mini"
        case "iPhone14,5" : return "iPhone 13"
        case "iPhone14,2" : return "iPhone 13 Pro"
        case "iPhone14,3" : return "iPhone 13 Pro Max"
        
        case "iPad1,1": return "iPad"
        case "iPad1,2": return "iPad 3G"
        case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4" : return "iPad 2"
        case "iPad2,5", "iPad2,6", "iPad2,7" : return "iPad Mini"
        case "iPad3,1", "iPad3,2", "iPad3,3" : return "iPad 3"
        case "iPad3,4", "iPad3,5", "iPad3,6" : return "iPad 4"
        case "iPad4,1", "iPad4,2", "iPad4,3" : return "iPad Air"
        case "iPad4,4", "iPad4,5", "iPad4,6" : return "iPad Mini 2"
        case "iPad4,7", "iPad4,8", "iPad4,9" : return "iPad Mini 3"
        case "iPad5,1", "iPad5,2" : return "iPad Mini 4"
        case "iPad5,3", "iPad5,4" : return "iPad Air 2"
        case "iPad6,3", "iPad6,4" : return "iPad Pro 9.7"
        case "iPad6,7", "iPad6,8" : return "iPad Pro 12.9"
        case "iPad6,11" : return "iPad 5 (WiFi)"
        case "iPad6,12" : return "iPad 5 (Cellular)"
        case "iPad7,1" : return "iPad Pro (12.9 inch, 2nd generation)"
        case "iPad7,2" : return "iPad Pro (12.9 inch, 2nd generation)"
        case "iPad7,3" : return "iPad Pro (10.5 inch)"
        case "iPad7,4" : return "iPad Pro (10.5 inch)"
        case "iPad7,5" : return "iPad 6 (WiFi)"
        case "iPad7,6" : return "iPad 6 (Cellular)"
        case "iPad7,11" : return "iPad 7 (WiFi)"
        case "iPad7,12" : return "iPad 7 (Cellular)"
        case "iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4" : return "iPad Pro (11 inch)"
        case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8" : return "iPad Pro (12.9 inch, 3rd generation)"
        case "iPad8,9", "iPad8,10" : return "iPad Pro (11 inch, 2nd generation)"
        case "iPad8,11", "iPad8,12" : return "iPad Pro (12.9 inch, 4th generation)"
        case "iPad11,1", "iPad11,2" : return "iPad mini (5th generation)"
        case "iPad11,3", "iPad11,4" : return "iPad Air (3rd generation)"
        case "iPad11,6" : return "iPad (WiFi)"
        case "iPad11,7" : return "iPad (Cellular)"
        case "iPad13,1", "iPad13,2" : return "iPad Air (4th generation)"
        case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7" : return "iPad Pro (11 inch, 3rd generation)"
        case "iPad13,8", "iPad13,9" : return "iPad Pro (12.9 inch, 5th generation)"
        case "iPad13,10", "iPad13,11" : return "iPad Pro (12.9 inch, 5th generation)"
        case "iPad14,1", "iPad14,2" : return "iPad mini (6th generation)"
        
        case "Watch1,1" : return "Apple Watch 38mm"
        case "Watch1,2" : return "Apple Watch 42mm"
        case "Watch2,3" : return "Apple Watch Series 2 38mm"
        case "Watch2,4" : return "Apple Watch Series 2 42mm"
        case "Watch2,6" : return "Apple Watch Series 1 38mm"
        case "Watch2,7" : return "Apple Watch Series 1 42mm"
        case "Watch3,1" : return "Apple Watch Series 3 38mm"
        case "Watch3,2" : return "Apple Watch Series 3 42mm"
        case "Watch3,3" : return "Apple Watch Series 3 38mm (LTE)"
        case "Watch3,4" : return "Apple Watch Series 3 42mm (LTE)"
        case "Watch4,1" : return "Apple Watch Series 4 40mm"
        case "Watch4,2" : return "Apple Watch Series 4 44mm"
        case "Watch4,3" : return "Apple Watch Series 4 40mm (LTE)"
        case "Watch4,4" : return "Apple Watch Series 4 44mm (LTE)"
        case "Watch5,1" : return "Apple Watch Series 5 40mm"
        case "Watch5,2" : return "Apple Watch Series 5 44mm"
        case "Watch5,3" : return "Apple Watch Series 5 40mm (LTE)"
        case "Watch5,4" : return "Apple Watch Series 5 44mm (LTE)"
        case "Watch5,9" : return "Apple Watch SE 40mm"
        case "Watch5,10" : return "Apple Watch SE 44mm"
        case "Watch5,11" : return "Apple Watch SE 40mm"
        case "Watch5,12" : return "Apple Watch SE 44mm"
        case "Watch6,1"  : return "Apple Watch Series 6 40mm"
        case "Watch6,2"  : return "Apple Watch Series 6 44mm"
        case "Watch6,3"  : return "Apple Watch Series 6 40mm"
        case "Watch6,4"  : return "Apple Watch Series 6 44mm"
            
        case "AudioAccessory1,1", "AudioAccessory1,2" : return "HomePod"
        case "AudioAccessory5,1" : return "HomePod mini"
            
        case "AirPods1,1" : return "AirPods (1st generation)"
        case "AirPods2,1" : return "AirPods (2nd generation)"
        case "iProd8,1"   : return "AirPods Pro"
        
        case "AppleTV2,1":  return "Apple TV 2"
        case "AppleTV3,1", "AppleTV3,2" : return "Apple TV 3"
        case "AppleTV5,3":  return "Apple TV 4"
        case "AppleTV6,2" : return "Apple TV 4K"
        
        case "i386", "x86_64" : return "Simulator"
        default:  return identifier
    }
    }

    //MARK:- 触动反馈
    static func doImpactFeedback(style : UIImpactFeedbackGenerator.FeedbackStyle = .light) {
        UIImpactFeedbackGenerator(style: style).impactOccurred()
    }

    //MARK:- UUID（Universally Unique Identifier）:通用唯一识别码，每次生成均不一样，所以第一次生成后需要保存到钥匙串，这样即使应用删除再重装仍然可以从钥匙串得到它
    static var UUID : String = {
        var uuid : String? = KeyChainManager.shared.getValue(for: "UUID")
        if uuid == nil {
            let puuid : CFUUID = CFUUIDCreate(nil)
            let uuidString : CFString = CFUUIDCreateString(nil, puuid)
            uuid = CFStringCreateCopy(nil, uuidString) as String?
            KeyChainManager.shared.set(value: uuid!, for: "UUID")
        }
        return uuid ?? ""
    }()
}
